# -*- coding: utf-8 -*-
from google.appengine.dist import use_library
use_library('django', '1.2')

import datetime,urllib, cgi, os
import logging
import User,Box,ext,app,hordissime
import s as secret

from google.appengine.api import memcache, urlfetch
from google.appengine.api.labs import taskqueue
from google.appengine.ext import webapp, db
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.runtime import apiproxy_errors
from xml.dom import minidom

from gaesessions import get_current_session
from Cookie import SimpleCookie as cookie
from db import Mp, User
from db import Thread

webapp.template.register_template_library('tag.filter')


class log(webapp.RequestHandler):
  def post(self):
	"""Page de login, récupération de la date de connexion, de l'avatar."""
	s = get_current_session()
	c = misc.get_cookie(self.request)

	key = self.request.get('key')
	skey = secret.key
	pseudo = ""

	# get xml
	try:
		url = "http://hordes.fr/xml/%s?k=%s;sk=%s"
		ame	= urlfetch.fetch(url%('ghost', key, skey)).content
		city= urlfetch.fetch(url%('', key, skey)).content
	except urlfetch.DownloadError:
		logging.error('Error while loading informations.')
		self.redirect('/?e=edown')
	except urlfetch.ResponseTooLargeError:
		logging.error('Response too large.')
		self.redirect('/?e=elong')
		return False
	# parse xml
	try:
		ame = minidom.parseString(ame)
		city = minidom.parseString(city)
	except:
		logging.error('Error while parsing XML.')
		self.redirect('/?e=eparse')
		return False

	# work with xml
	citizen = ame.getElementsByTagName('citizen')
	headers = ame.getElementsByTagName('headers')
	pseudo = citizen[0].attributes['name'].value
	uid    = citizen[0].attributes['id'].value

	logging.info('%s se connecte'%pseudo)
	s['pseudo'] = pseudo
	c['pseudo'] = pseudo
	
# get user identity or create one
	me = User()
	try:
		me = User.read(uid)
	except apiproxy_errors.OverQuotaError:
		self.redirect('/guest?e=ovrqota')
		return
	# if no data found, check if an format is stored
	if not me:
		old = User.check(pseudo)
		if old is not None:
			me = User.convert(uid, old)
		else:
			me = User.create(uid)
			me.name = pseudo.lower()
#update data about user
	try:
		me.avatar = urlfetch.Fetch('%s%s'% \
			(headers[0].attributes['avatarurl'].value,\
			 citizen[0].attributes['avatar'].value)).content
	except:
		me.avatar = ""
	nowCity = ''
	try:
		nowCity = city.getElementsByTagName('city')[0].attributes['city'].value
	except:
		nowCity = u'Ancienne Cité oubliée'
	me.nowCity = nowCity
	me.update()

	if s['pseudo'] != c['pseudo'].value:
		logging.error('Error with session and cookies.')
		self.redirect('/?e=ecookie')
		return False
	misc.add_cookie(c, self.response)
	self.redirect('/')

  def get(self):
	"""bloque la connexion en get si on est pas en Dev"""

	pseudo = self.request.get('p')
	uid    = self.request.get('u')
	if not os.environ['SERVER_SOFTWARE'].startswith('Dev'):
		self.redirect('/?e')
		return True
	else:
		s = get_current_session()
		c = misc.get_cookie(self.request)
		s['pseudo'] = pseudo
		s['uid'] = uid
		c['pseudo'] = pseudo
		misc.add_cookie(c, self.response)
		me = User.create(s['uid'])
		self.redirect('/')

class display(webapp.RequestHandler):
  def get(self):
	"""Affichage de la liste de discussion désirée"""
	s = get_current_session()
	c = misc.get_cookie(self.request)
	try:	pseudo = s['pseudo']
	except: pseudo = c['pseudo'].value
	kind = self.request.get('type')

	# récupère les messages de la bonnes boites, pour afficher la liste.
	threads = {
			''		: Thread.all().filter('destin IN', (pseudo, pseudo.lower())).filter('stateIn <', 2),
			'pack'  : Thread.all().filter('destin IN', (pseudo, pseudo.lower())).filter('stateOut', 2),
			'send'	: Thread.all().filter('author IN', (pseudo, pseudo.lower())),
		}[kind]

	# get the thread
	key = db.Key(self.request.get('read'))
	thread = Thread.get(key)
	read = Mp.get(thread.msgs)

	# les messages sont lu et le thread
	for m in read:
		if m.state < 2 and pseudo.lower() == m.destin.lower():
			m.state = 1
			m.put()
	if thread.stateOut < 2 and pseudo.lower() == thread.author.lower():
		thread.stateOut = 1
		thread.put()
	if thread.stateIn < 2 and pseudo.lower() == thread.destin.lower():
		thread.stateIn = 1
		thread.put()

	# pour le champ de réponse
	if thread.destin.lower() == pseudo.lower():
		to = thread.author
	else:
		to = thread.destin

	template_values = {
		'threads'	: threads,
		'mp'		: read,
		'thread'	: thread,
		'to'		: to,
		'sub'		: thread.subject,
		'pseudo'	: pseudo,
		'type'		: kind,
		'e'			: self.request.get('e'),
		'cite'		: read[len(read)-1].key(),
	}
	path = os.path.join(os.path.dirname(__file__), 'views/read.html')
	self.response.out.write(template.render(path, template_values))

class packing(webapp.RequestHandler):
  def get(self):
	"""archivage"""
	s = get_current_session()
	c = misc.get_cookie(self.request)
	try:	pseudo = s['pseudo']
	except: pseudo = c['cookie'].value

	key = db.Key(self.request.get('read'))
	thread = Thread.all().filter('__key__ = ', key).get()
	cats = {
			"not":0,
			"read":1,
			"pack":2,
			"bann":3,
			"warn":4,
			}

	if thread.author == pseudo:
		self.response.out.write("author")
		thread.stateOut = cats[self.request.get('cat')]
	if thread.destin == pseudo:
		self.response.out.write("destin")
		thread.stateIn = cats[self.request.get('cat')]
	thread.put()
	if cats[self.request.get('cat')] < 2:
		self.redirect('/?e=okcat')
	else:
		self.redirect('/pack?e=okcat')

class add(webapp.RequestHandler):
  def post(self):
	"""ajout de message au datastore"""
	s = get_current_session()
	c = misc.get_cookie(self.request)

	if self.request.get('destin')  == '':
		self.redirect('/?e=missingfield')
		return False
	if self.request.get('subject') == '':
		self.redirect('/?e=missingfield')
		return False

	secure = True

	try:	s['pseudo'] 
	except:
		logging.warning('s.pseudo undefined');
		pseudo = c['pseudo'].value
		secure = False
	pseudo = s['pseudo']
	secure = True
		

	if not secure and pseudo in secret.admin:
		self.redirect('/?e=badfield')
		return False

	message = Mp()

	message.author  = cgi.escape(pseudo)
	message.destin  = cgi.escape(self.request.get('destin').lower())
	message.subject = cgi.escape(self.request.get('subject'))
	message.message = cgi.escape(self.request.get('message'))
	message.state   = 0
	message.secure  = secure
	test = message.put()

	if test:
		self.response.out.write('msg ok')
		destin = self.request.get('destin').lower()
		sender = self.request.get('author').lower()
		subject = self.request.get('subject')
		alertIm = taskqueue.Task(url='/out/im',
					params={'destin':destin,'sender':sender,'subject':subject
								})
		alertIm.add('im')
		try:
			threadKey = self.request.get('thread')
			oldThread = Thread().get(threadKey)
			oldThread.msgs.append(test)
			if oldThread.destin.lower() == pseudo.lower():
				[oldThread.destin,oldThread.author] = [oldThread.author,oldThread.destin]
			oldThread.stateIn = 0
			oldThread.put()
		except:
			newThread = Thread()
			newThread.author = cgi.escape(sender)
			newThread.destin = cgi.escape(destin)
			newThread.subject =  cgi.escape(self.request.get('subject'))
			newThread.msgs = [test]
			newThread.last = datetime.datetime.today()
			newThread.stateOut = 1
			newThread.stateIn = 0
			newThread.put()
	else:
		self.response.out.write('problem')
		logging.warning('failure while adding a message')
		return False	
	self.redirect('/send?e=okmsg')

class guest(webapp.RequestHandler):
	def get(self):
		tpl_val = {
			'e'		: self.request.get('e'),
			'pseudo': '_',
		}
		path = os.path.join(os.path.dirname(__file__), 'views/guest.html')
		self.response.out.write(template.render(path, tpl_val))

application = webapp.WSGIApplication([	# box.py
										('/',		Box.InboxHandler),
										('/send',	Box.OutboxHandler),
										('/pack',	Box.PackedHandler),
										# mp.py
										('/mp',		display),
										('/packing',packing),
										('/log',	log),
										('/add',	add),
										('/guest',	guest),
										# misc.py	
										('/rep/?(.*)/?', User.rep),
										('/set/?(.*)/?', User.setting),
										('/profil/(.*)', User.profil),
										('/avatar/(.*)', User.avatar),
										# ext.py
										(r'/status/(.*)/(.*)', ext.status),
										# app.py
										(r'/app/test', app.dummy),
										(r'/app/send', app.send),
										# hordissime.py
										(r'/hordissime', hordissime.call),
									], debug=True)

def main():
  run_wsgi_app(application)

if __name__ == "__main__":
  main()

